<template>
  <view class="container">
    <view class="header">
      <text class="title">智能锁状态监控</text>
    </view>

    <view class="section">
      <button @click="initBluetooth" type="primary">初始化蓝牙</button>
      <button @click="scanDevices" type="primary">扫描设备</button>

      <button @click="aesEncrypt">aesEncrypt</button>
    </view>

    <view class="section" v-if="devices.length">
      <text class="section-title">发现设备:</text>
      <radio-group @change="deviceChange">
        <label
          class="device-item"
          v-for="(item, index) in devices"
          :key="index"
        >
          <radio
            :value="item.deviceId"
            :checked="currentDeviceId === item.deviceId"
          />
          {{ item.MAC }}
          {{ item.name }} ({{ item.deviceId }}) - 电量: {{ item.power }}% -
          状态: {{ item.lockState === 0 ? "开" : "关" }}
        </label>
      </radio-group>
    </view>

    <view class="section" v-if="currentDeviceId">
      <button @click="connectDevice" type="primary">连接设备</button>
      <button
        @click="queryDetailedStatus"
        type="primary"
        :disabled="!connected"
      >
        查询详细状态
      </button>
      <button @click="disconnectDevice" type="warn" :disabled="!connected">
        断开连接
      </button>
      <button @click="unlockDevice" type="primary">开锁</button>

      <!-- 关锁 -->
      <button @click="lockDevice" type="primary">关锁</button>

      <button @click="bleGetToken" type="primary">获取token</button>

      <button @click="getNbTest" type="primary">Http获取</button>
    </view>

    <view class="status-info" v-if="connected">
      <text class="info-title">当前锁状态:</text>
      <text>基础状态: {{ basicStatus.lockState === 0 ? "开" : "关" }}</text>
      <text>电量: {{ basicStatus.power }}%</text>
      <text v-if="detailedStatus"
        >磁铁状态: {{ detailedStatus.sta === 1 ? "吸住" : "拿开" }}</text
      >
      <text v-if="detailedStatus"
        >锁舌状态: {{ detailedStatus.latc === 1 ? "伸出" : "压入" }}</text
      >
    </view>

    <view class="log-container">
      <text class="log-title">操作日志:</text>
      <scroll-view scroll-y class="log-content">
        <text v-for="(log, index) in logs" :key="index" class="log-item">{{
          log
        }}</text>
      </scroll-view>
    </view>
  </view>
</template>

<script>
// AES加密库（需要自行引入或实现）
const CryptoJS = require("crypto-js");
var fun_aes = require("utils/aes.js");
// ArrayBuffer转16进度字符串示例
function ab2hex(buffer) {
  const hexArr = Array.prototype.map.call(
    new Uint8Array(buffer),
    function (bit) {
      return ("00" + bit.toString(16)).slice(-2);
    }
  );
  return hexArr.join("");
}
export default {
  data() {
    return {
      bluetoothEnabled: false,
      devices: [],
      currentDeviceId: "",
      connected: false,
      basicStatus: {
        lockState: null,
        power: null,
      },
      detailedStatus: null,
      logs: [],
      // AES初始密钥（来自协议文档）
      aesKey: [
        0x3a, 0x60, 0x43, 0x2a, 0x5c, 0x01, 0x21, 0x1f, 0x29, 0x1e, 0x0f, 0x4e,
        0x0c, 0x13, 0x28, 0x25,
      ],
      token: null,
      serviceId: "0000FEE7-0000-1000-8000-00805F9B34FB",
      writeCharId: "000036F5-0000-1000-8000-00805F9B34FB",
      readCharId: "0000FEC9-0000-1000-8000-00805F9B34FB",
      notifyCharId: "000036F6-0000-1000-8000-00805F9B34FB",
      tokenCmd: [6, 1, 1, 1, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12],

      // 蓝牙令牌
      lanYaToken: [],
      currentFragment: 1,
      httpUrl: "",
    };
  },
  methods: {
    aesEncrypt: function (array) {
      const INITIAL_KEY = [
        0x3a, 0x60, 0x43, 0x2a, 0x5c, 0x01, 0x21, 0x1f, 0x29, 0x1e, 0x0f, 0x4e,
        0x0c, 0x13, 0x28, 0x25,
      ];

      var acontent = array;
      var contentWA = fun_aes.CryptoJS.enc.int8array.parse(acontent);

      const key = fun_aes.CryptoJS.enc.int8array.parse(INITIAL_KEY);

      const encrypted = fun_aes.CryptoJS.AES.encrypt(contentWA, key, {
        mode: CryptoJS.mode.ECB,
        padding: CryptoJS.pad.NoPadding,
      });

      var bv = fun_aes.CryptoJS.enc.int8array.stringify(encrypted.ciphertext);

      return bv;
    },

    /**
     * 发送获取Token的请求
     */
    bleGetToken: function () {
      //命令格式
      //0x06	0x01	0x01	0x01
      const _token = [];
      const _that = this;
      for (let i = 0; i < _that.tokenCmd.length; i++) {
        if (i <= 3) {
          //
          _token.push(_that.tokenCmd[i]);
          continue;
        }
        const _num = Math.round(Math.random() * 100);
        _that.tokenCmd.splice(i, 1, _num);
        _token.push(_num);
      }

      _that.commDevice(_token);
    },

    //  NB测试
    async getNbTest() {
      // const _that = this;
      let _locakCmd = [14, 7, 1, 1];

      this.token.forEach((item, index) => {
        _locakCmd.push(item);
      });

      for (let i = 0; i <= 7; i++) {
        _locakCmd.push(Math.round(Math.random() * 100));
      }

      const encrypted = this.aesEncrypt(_locakCmd);
      if (!encrypted) {
        throw new Error("加密失败");
      }

      console.log("获取域名: ", { 加密后: encrypted, 加密前: _locakCmd });

      await this.writeBLEValue(encrypted.buffer);

      const result = await this.getHttpCallback(50000);
    },
    /**
     * 与设备交互
     */
    commDevice: function (cmd) {
      const encrypted = this.aesEncrypt(cmd);
      this.writeCharacterData(encrypted.buffer);
    },
    /**
     * 写数据
     */
    writeCharacterData: function (buffer) {
      var that = this;

      wx.writeBLECharacteristicValue({
        deviceId: this.currentDeviceId,
        serviceId: this.serviceId,
        characteristicId: this.writeCharId,
        value: buffer,
        success: function (res) {
          // success
          console.log("writeCharacterData succ" + res.errMsg);
        },
        fail: function (res) {
          // fail
          console.log("writeCharacterData fail" + JSON.stringify(res));
        },
        complete: function (res) {
          // complete
          console.log("writeCharacterData complete" + JSON.stringify(res));
        },
      });
    },
    addLog(message) {
      this.logs.unshift(`[${new Date().toLocaleTimeString()}] ${message}`);
      if (this.logs.length > 50) {
        this.logs.pop();
      }
    },

    // 初始化蓝牙适配器
    initBluetooth() {
      this.addLog("正在初始化蓝牙适配器...");
      uni.openBluetoothAdapter({
        success: (res) => {
          this.bluetoothEnabled = true;
          this.addLog("蓝牙适配器初始化成功");
          this.listenBluetoothEvents();
        },
        fail: (err) => {
          this.addLog("蓝牙适配器初始化失败: " + JSON.stringify(err));
          uni.showToast({
            title: "蓝牙初始化失败",
            icon: "none",
          });
        },
      });
    },
    arrayBufferToHexString: function (buffer) {
      if (buffer != "[object ArrayBuffer]") {
        return;
      }
      let dataView = new DataView(buffer);

      var hexStr = "";
      for (var i = 0; i < dataView.byteLength; i++) {
        var str = dataView.getUint8(i);
        var hex = (str & 0xff).toString(16);
        hex = hex.length === 1 ? "0" + hex : hex;
        hexStr += hex;
      }

      return hexStr.toUpperCase();
    },

    // 监听蓝牙事件
    listenBluetoothEvents() {
      // 监听蓝牙适配器状态变化
      uni.onBluetoothAdapterStateChange((res) => {
        console.log("onBluetoothAdapterStateChange", res);
        this.addLog(
          `蓝牙适配器状态变化: 可用=${res.available}, 搜索中=${res.discovering}`
        );
        this.bluetoothEnabled = res.available;
      });

      // 监听设备发现事件
      uni.onBluetoothDeviceFound((res) => {
        console.log("resresres", res);

        var deviceName = res.devices[0].localName;

        // log

        res.devices.forEach((device) => {
          if (!device.advertisData) return;

          // 解析广播数据
          const parsedData = this.parseAdvertData(device.advertisData);

          var macAddressTmp = this.arrayBufferToHexString(
            // devices.devices[0].advertisData
            device.advertisData
          );
          // console.log("获取广播数据", parsedData);

          // var resultArray = new Int8Array(device.advertisData);

          // const decrypted = this.decryptData(resultArray);

          var tmpLength = macAddressTmp.length;

          if (tmpLength >= 16) {
            var macAddress =
              macAddressTmp.substring(4, 6) +
              ":" +
              macAddressTmp.substring(6, 8) +
              ":" +
              macAddressTmp.substring(8, 10) +
              ":" +
              macAddressTmp.substring(10, 12) +
              ":" +
              macAddressTmp.substring(12, 14) +
              ":" +
              macAddressTmp.substring(14, 16);
          }

          console.log("获取广播数据", {
            deviceName,
            macAddressTmp,
            macAddress,
            device,
          });

          if (
            parsedData &&
            (parsedData.PRO === "0102" || parsedData.PRO === "1111")
          ) {
            const existingIndex = this.devices.findIndex(
              (d) => d.deviceId === device.deviceId
            );
            const deviceInfo = {
              deviceId: device.deviceId,
              name: device.name || "未知设备",
              power: parsedData.POWER,
              lockState: parsedData.LOCK_STATE,
              ...parsedData,
            };

            if (existingIndex >= 0) {
              this.devices.splice(existingIndex, 1, deviceInfo);
            } else {
              this.devices.push(deviceInfo);
              this.addLog(`发现新设备: ${device.name || device.deviceId}`);
            }

            // 更新基础状态
            if (device.deviceId === this.currentDeviceId) {
              this.basicStatus = {
                lockState: parsedData.LOCK_STATE,
                power: parsedData.POWER,
              };
            }
          }
        });
      });
    },

    // 解析广播数据
    parseAdvertData(buffer) {
      try {
        if (!buffer || buffer.byteLength < 9) return null;

        const dataView = new DataView(buffer);
        // 前2字节是PRO
        const PRO = dataView.getUint16(0, false).toString(16).padStart(4, "0");
        // 接下来6字节是MAC地址
        const MAC = Array.from({ length: 6 }, (_, i) =>
          dataView
            .getUint8(2 + i)
            .toString(16)
            .padStart(2, "0")
        ).join(":");
        // 第9字节是电量(0-100)
        const POWER = dataView.getUint8(8);
        // 第10字节是锁状态(如果有)
        const LOCK_STATE = buffer.byteLength > 9 ? dataView.getUint8(9) : null;

        return { PRO, MAC, POWER, LOCK_STATE };
      } catch (e) {
        console.error("解析广播数据失败:", e);
        return null;
      }
    },

    // 扫描设备
    scanDevices() {
      this.addLog("开始扫描设备...");
      this.devices = [];
      uni.startBluetoothDevicesDiscovery({
        // services: [this.serviceId],
        success: (res) => {
          this.addLog("扫描已启动");

          console.log("扫描已启动", res);

          // 3秒后自动停止扫描
          setTimeout(() => {
            uni.stopBluetoothDevicesDiscovery();
            this.addLog("扫描已停止");
          }, 5000);
        },
        fail: (err) => {
          this.addLog("扫描失败: " + JSON.stringify(err));
          console.log("errerr", err);
        },
      });
    },

    // 选择设备
    deviceChange(e) {
      this.currentDeviceId = e.detail.value;
      const device = this.devices.find(
        (d) => d.deviceId === this.currentDeviceId
      );
      if (device) {
        this.basicStatus = {
          lockState: device.lockState,
          power: device.power,
        };
        this.addLog(`已选择设备: ${device.name || device.deviceId}`);
      }
    },

    // 连接设备
    connectDevice() {
      if (!this.currentDeviceId) {
        this.addLog("请先选择设备");
        return;
      }

      this.addLog(`正在连接设备: ${this.currentDeviceId}`);
      uni.createBLEConnection({
        deviceId: this.currentDeviceId,
        success: (res) => {
          this.addLog("设备连接成功");
          this.connected = true;
          this.getDeviceServices();
          console.log("连接成功", res);
        },
        fail: (err) => {
          this.addLog("设备连接失败: " + JSON.stringify(err));
        },
      });
    },

    // 获取设备服务
    getDeviceServices() {
      uni.getBLEDeviceServices({
        deviceId: this.currentDeviceId,
        success: (res) => {
          this.addLog(
            `发现服务: ${res.services.map((s) => s.uuid).join(", ")}`
          );
          this.getDeviceCharacteristics();

          console.log("获取蓝牙设备所有服务(service)", res);
        },
        fail: (err) => {
          this.addLog("获取服务失败: " + JSON.stringify(err));
        },
      });
    },

    // 获取特征值
    getDeviceCharacteristics() {
      uni.getBLEDeviceCharacteristics({
        deviceId: this.currentDeviceId,
        serviceId: this.serviceId,
        success: (res) => {
          this.addLog(
            `发现特征值: ${res.characteristics.map((c) => c.uuid).join(", ")}`
          );

          console.log("特征值", res);

          wx.onBLECharacteristicValueChange(function (characteristic) {
            console.log("监听特征值变化", characteristic);
          });

          wx.notifyBLECharacteristicValueChange({
            deviceId: this.currentDeviceId,
            serviceId: this.serviceId,
            characteristicId: this.notifyCharId,
            state: true,
            success: (res) => {
              console.log("已启用通知", res);
              this.getToken(); // 获取Token后才能执行其他命令
            },
            fail: (err) => {
              this.addLog("启用通知失败: " + JSON.stringify(err));
            },
            complete: (res) => {
              uni.onBLECharacteristicValueChange((res) => {
                console.log("接收到数据", res);
              });
            },
            type: "notification",
          });
        },
        fail: (err) => {
          this.addLog("获取特征值失败: " + JSON.stringify(err));
          console.log("获取特征值失败", {
            err,
            deviceId: this.currentDeviceId,
            serviceId: this.serviceId,
          });
        },
      });
    },

    // 获取Token
    // 优化后的获取Token方法
    async getToken() {
      this.addLog("正在获取Token...");

      try {
        // 获取Token命令: 0x06 0x01 0x01 0x01
        const cmd = new Int8Array(16);
        cmd.set([0x06, 0x01, 0x01, 0x01]);

        // 填充随机数 (协议要求命令总长固定为16字节，不足的用随机数补足)
        for (let i = 4; i < 16; i++) {
          cmd[i] = Math.round(Math.random() * 100);
        }

        const encrypted = this.encryptData(cmd);
        if (!encrypted) {
          throw new Error("加密失败");
        }

        // console.log("测试数据: ", { 加密后: encrypted, 加密前: cmd });

        await this.writeBLEValue(encrypted.buffer);
        // this.addLog("Token请求已发送");

        // 等待Token响应 (超时5秒)
        const token = await this.waitForTokenResponse(50000);
        console.log("获取到了token啊啊啊啊啊", token);

        if (token) {
          this.token = token;
          this.addLog(`获取Token成功: ${this.bytesToHex(this.token)}`);
        } else {
          throw new Error("获取Token超时");
        }
      } catch (err) {
        this.addLog(`获取Token失败: ${err.message}`);
        this.token = null;
      }
    },

    // 等待Token响应
    waitForTokenResponse(timeout) {
      return new Promise((resolve) => {
        let timer;

        // 临时监听Token响应
        const handler = (res) => {
          console.log("接受token相应", res.value);

          const result = res.value;
          var resultArray = new Int8Array(result);

          const decrypted = this.decryptData(resultArray);
          console.log("解密", decrypted);

          console.log("decrypted[0]", decrypted[0]);

          if (!decrypted) return;

          // 检查是否为Token响应 (0x06 0x02)
          if (decrypted[0] == 6 && decrypted[1] == 2) {
            clearTimeout(timer);
            uni.offBLECharacteristicValueChange(handler);
            resolve(decrypted.slice(3, 7)); // 提取4字节Token
          }
        };

        uni.onBLECharacteristicValueChange(handler);

        // 设置超时
        timer = setTimeout(() => {
          uni.offBLECharacteristicValueChange(handler);
          resolve(null);
        }, timeout);
      });
    },

    // 等待关锁回调
    waitCloseLock: function (timeout) {
      return new Promise((resolve, reject) => {
        let timer = null;
        const handler = (res) => {
          const result = res.value;
          var resultArray = new Int8Array(result);

          const decrypted = this.decryptData(resultArray);
          console.log("waitCloseLock解密", decrypted);
        };
        uni.onBLECharacteristicValueChange(handler);
      });
    },

    // 获取http回调
    getHttpCallback: function () {
      return new Promise((resolve, reject) => {
        let timer = null;
        const handler = (res) => {
          const result = res.value;
          var resultArray = new Int8Array(result);

          const decrypted = this.decryptData(resultArray);
          console.log("获取http回调", decrypted);
          this.httpUrl = "";
        };
        uni.onBLECharacteristicValueChange(handler);
      });
    },

    char2buf: function (e) {
      for (
        var t = new ArrayBuffer(2 * e.length),
          a = new Uint16Array(t),
          o = e.split(""),
          c = 0;
        c < o.length;
        c++
      )
        a[c] = o[c].charCodeAt();
      return t;
    },

    async lockDevice() {
      let _locakCmd = [5, 12, 1, 1];

      this.token.forEach((item, index) => {
        _locakCmd.push(item);
      });

      for (let i = 0; i <= 7; i++) {
        _locakCmd.push(Math.round(Math.random() * 100));
      }

      const encrypted = this.aesEncrypt(_locakCmd);
      if (!encrypted) {
        throw new Error("加密失败");
      }

      console.log("关锁测试数据: ", { 加密后: encrypted, 加密前: _locakCmd });

      await this.writeBLEValue(encrypted.buffer);

      const result = await this.waitCloseLock(50000);
    },
    // 开锁功能
    async unlockDevice() {
      let _locakCmd = [5, 1, 6];

      for (let i = 0; i <= 5; i++) {
        _locakCmd.push(48);
      }

      this.token.forEach((item, index) => {
        _locakCmd.push(item);
      });

      // 三个随机数
      for (let i = 0; i < 3; i++) {
        const _num = Math.round(Math.random() * 100);
        _locakCmd.push(_num);
      }

      const encrypted = this.aesEncrypt(_locakCmd);
      if (!encrypted) {
        throw new Error("加密失败");
      }

      console.log("开锁功能: ", { 加密后: encrypted, 加密前: _locakCmd });

      await this.writeBLEValue(encrypted.buffer);

      const result = await this.waitCloseLock(50000);
    },

    // 等待开锁响应
    waitForUnlockResponse(timeout) {
      return new Promise((resolve) => {
        let timer;

        // 临时监听开锁响应
        const handler = (res) => {
          const decrypted = this.decryptData(res.value);
          if (!decrypted) return;

          // 检查是否为开锁响应 (0x05 0x02)
          if (decrypted[0] === 0x05 && decrypted[1] === 0x02) {
            clearTimeout(timer);
            uni.offBLECharacteristicValueChange(handler);
            resolve(decrypted[3]); // 返回结果 (0x00成功, 0x01失败)
          }
        };

        uni.onBLECharacteristicValueChange(handler);

        // 设置超时
        timer = setTimeout(() => {
          uni.offBLECharacteristicValueChange(handler);
          resolve(null);
        }, timeout);
      });
    },

    // 封装BLE写入操作
    writeBLEValue(value) {
      return new Promise((resolve, reject) => {
        uni.writeBLECharacteristicValue({
          deviceId: this.currentDeviceId,
          serviceId: this.serviceId,
          characteristicId: this.writeCharId,
          value: value,
          success: resolve,
          fail: reject,
        });
      });
    },

    // 查询详细状态
    async queryDetailedStatus() {
      if (!this.token) {
        this.addLog("请先获取Token");
        return;
      }

      this.addLog("正在查询详细状态...");
      let queryDetailedCmd = [5, 14, 1, 1];

      this.token.forEach((item, index) => {
        queryDetailedCmd.push(item);
      });

      for (let i = 0; i <= 7; i++) {
        queryDetailedCmd.push(Math.round(Math.random() * 100));
      }

      const encrypted = this.aesEncrypt(queryDetailedCmd);
      if (!encrypted) {
        throw new Error("加密失败");
      }

      console.log("查询详细状态: ", {
        加密后: encrypted,
        加密前: queryDetailedCmd,
      });

      await this.writeBLEValue(encrypted.buffer);

      const result = await this.waitCloseLock(50000);
    },

    // 发送命令
    sendCommand(cmdArray) {
      if (cmdArray.length !== 16) {
        this.addLog("命令长度必须为16字节");
        return;
      }

      const encrypted = this.encryptData(cmdArray);
      if (!encrypted) {
        this.addLog("加密命令失败");
        return;
      }

      uni.writeBLECharacteristicValue({
        deviceId: this.currentDeviceId,
        serviceId: this.serviceId,
        characteristicId: this.writeCharId,
        value: encrypted.buffer,
        success: (res) => {
          this.addLog("命令发送成功");
        },
        fail: (err) => {
          this.addLog("命令发送失败: " + JSON.stringify(err));
        },
      });
    },

    // 断开连接
    disconnectDevice() {
      uni.closeBLEConnection({
        deviceId: this.currentDeviceId,
        success: (res) => {
          this.addLog("设备已断开");
          this.connected = false;
          this.token = null;
          this.detailedStatus = null;
        },
        fail: (err) => {
          this.addLog("断开连接失败: " + JSON.stringify(err));
        },
      });
    },

    // AES加密
    encryptData(data) {
      try {
        const aesKey = [
          0x3a, 0x60, 0x43, 0x2a, 0x5c, 0x01, 0x21, 0x1f, 0x29, 0x1e, 0x0f,
          0x4e, 0x0c, 0x13, 0x28, 0x25,
        ];
        const keyBytes = CryptoJS.enc.Utf8.parse(new Int8Array(aesKey));
        const dataBytes = CryptoJS.enc.Utf8.parse(data);
        // AES-128 ECB模式加密，无填充
        const encrypted = CryptoJS.AES.encrypt(dataBytes, keyBytes, {
          mode: CryptoJS.mode.ECB,
          padding: CryptoJS.pad.NoPadding,
        });

        // 返回Uint8Array
        return new Int8Array(encrypted.ciphertext.words);
      } catch (e) {
        console.error("加密失败:", e);
        return null;
      }
    },

    // AES解密
    decryptData(data) {
      var that = this;
      var acontent = data;
      console.log("Decrypt acontent is " + acontent);
      // 将密文转换成WordArray
      var contentWA = fun_aes.CryptoJS.enc.int8array.parse(acontent);
      console.log("Decrypt contentWA is " + contentWA);
      // 插件要求密文是base64格式
      var dcBase64String = contentWA.toString(fun_aes.CryptoJS.enc.Base64);
      console.log("Decrypt dcBase64String is " + dcBase64String);

      const keyWA = fun_aes.CryptoJS.enc.int8array.parse(new Int8Array());

      const INITIAL_KEY = [
        0x3a, 0x60, 0x43, 0x2a, 0x5c, 0x01, 0x21, 0x1f, 0x29, 0x1e, 0x0f, 0x4e,
        0x0c, 0x13, 0x28, 0x25,
      ];

      const key = fun_aes.CryptoJS.enc.int8array.parse(INITIAL_KEY);

      // 解密 选定mode是CFB类型，无偏移量
      var decrypted = fun_aes.CryptoJS.AES.decrypt(dcBase64String, key, {
        // iv: that.globalData.bleVariable.ivWA,
        mode: fun_aes.CryptoJS.mode.ECB,
        padding: fun_aes.CryptoJS.pad.NoPadding,
      });
      console.log("解密了，内容是=== " + decrypted);
      // 将解密后的明文转回int8数组
      var bv = fun_aes.CryptoJS.enc.int8array.stringify(decrypted);
      return bv;

      return;
      try {
        // 将密钥转换为CryptoJS格式
        const keyBytes = CryptoJS.lib.WordArray.create(
          new Uint8Array(this.aesKey)
        );
        // 将数据转换为CryptoJS格式
        const encryptedData = CryptoJS.lib.WordArray.create(
          new Uint8Array(data)
        );
        // AES-128 ECB模式解密，无填充
        const decrypted = CryptoJS.AES.decrypt(
          { ciphertext: encryptedData },
          keyBytes,
          { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.NoPadding }
        );
        // 返回Uint8Array
        return new Uint8Array(decrypted.words.buffer);
      } catch (e) {
        console.error("解密失败:", e);
        return null;
      }
    },

    // 字节数组转十六进制字符串
    bytesToHex(bytes) {
      return Array.from(bytes)
        .map((b) => b.toString(16).padStart(2, "0"))
        .join(" ");
    },
  },
  onUnload() {
    if (this.connected) {
      this.disconnectDevice();
    }
    uni.closeBluetoothAdapter();
  },
};
</script>

<style>
.container {
  padding: 20rpx;
  display: flex;
  flex-direction: column;
}

.header {
  margin-bottom: 30rpx;
}

.title {
  font-size: 36rpx;
  font-weight: bold;
}

.section {
  margin-bottom: 30rpx;
}

.section-title {
  font-size: 32rpx;
  font-weight: bold;
  margin-bottom: 10rpx;
  display: block;
}

.device-item {
  display: block;
  padding: 15rpx;
  border-bottom: 1rpx solid #eee;
}

.status-info {
  background-color: #f5f5f5;
  padding: 20rpx;
  border-radius: 10rpx;
  margin-bottom: 30rpx;
}

.info-title {
  font-size: 32rpx;
  font-weight: bold;
  margin-bottom: 10rpx;
  display: block;
}

.log-container {
  border: 1rpx solid #eee;
  border-radius: 10rpx;
  padding: 15rpx;
  margin-top: 30rpx;
}

.log-title {
  font-size: 32rpx;
  font-weight: bold;
  margin-bottom: 10rpx;
  display: block;
}

.log-content {
  height: 300rpx;
}

.log-item {
  display: block;
  font-size: 24rpx;
  color: #666;
  margin-bottom: 5rpx;
  word-break: break-all;
}

button {
  margin-bottom: 20rpx;
}
</style>
